﻿// Copyright © 2011 Paul Vanukoff (pvanukoff@gmail.com)

using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
using Bravura.Native.PluginBase;

namespace Bravura.Native.WaveformTool
{
	public partial class MainForm : Form
	{
		#region Fields

		decimal _decay = 0.0M;
		decimal _phase = 0.0M;
		decimal _combFreq = 0.0M;
		decimal _combPhase = 0.0M;
		double[] _waveData = null;
		Random _random = new Random();

		#endregion

		public MainForm()
		{
			InitializeComponent();
			handleValuesChanged();
		}

		#region Private Methods

		private void handleValuesChanged()
		{
			while (numPhase.Value > 1.0M) numPhase.Value -= 1.0M;
			while (numPhase.Value < -1.0M) numPhase.Value += 1.0M;
			while (numCombFreq.Value > 1.0M) numCombFreq.Value -= 1.0M;
			while (numCombFreq.Value < -1.0M) numCombFreq.Value += 1.0M;
			while (numCombPhase.Value > 1.0M) numCombPhase.Value -= 1.0M;
			while (numCombPhase.Value < -1.0M) numCombPhase.Value += 1.0M;

			_decay = numDecay.Value;
			_phase = numPhase.Value;
			_combFreq = numCombFreq.Value;
			_combPhase = numCombPhase.Value;

			int size = (int)numSize.Value;
			double decay = (double)_decay;
			double phase = (double)_phase;
			double combFreq = (double)_combFreq;
			double combPhase = (double)_combPhase;
			
			_waveData = Utilities.BuildFourierBasicWaveform(size, decay, phase, combFreq, combPhase);
			
			picWaveform.Invalidate();
		}

		#endregion 

		#region Control Events

		private void picWaveform_Paint(object sender, PaintEventArgs e)
		{
			if (_waveData != null)
			{
				Graphics g = e.Graphics;
				g.SmoothingMode = SmoothingMode.AntiAlias;
				Pen pen = new Pen(Color.LimeGreen, 2f);

				int dataLen = _waveData.Length;
				float myWidth = g.ClipBounds.Width;
				float myHeight = g.ClipBounds.Height;
				float middle = myHeight / 2f;
				float amp = 0.25f * myHeight;
				float xk = myWidth / dataLen;

				g.DrawLine(Pens.Green, 0, middle, myWidth, middle);

				for (int i = 0; i < dataLen; i++)
				{
					float x0 = i * xk;
					float x1 = x0 + xk;
					float y0 = middle + amp * (float)_waveData[i];
					float y1 = middle + amp * (float)_waveData[(i + 1) % dataLen];
					g.DrawLine(pen, x0, y0, x1, y1);
				}
			}
		}

		private void numSize_ValueChanged(object sender, EventArgs e)
		{
			handleValuesChanged();
		}

		private void numDecay_ValueChanged(object sender, EventArgs e)
		{
			handleValuesChanged();
		}

		private void numPhasePer_ValueChanged(object sender, EventArgs e)
		{
			handleValuesChanged();
		}

		private void numCombFreq_ValueChanged(object sender, EventArgs e)
		{
			handleValuesChanged();
		}

		private void numCombPhase_ValueChanged(object sender, EventArgs e)
		{
			handleValuesChanged();
		}

		private void buttonSquare_Click(object sender, EventArgs e)
		{
			numDecay.Value = 1.00M;
			numPhase.Value = 0.00M;
			numCombFreq.Value = 0.25M;
			numCombPhase.Value = 0.25M;
		}

		private void buttonSaw_Click(object sender, EventArgs e)
		{
			numDecay.Value = 1.00M;
			numPhase.Value = 0.25M;
			numCombFreq.Value = 0.00M;
			numCombPhase.Value = 0.00M;
		}

		private void buttonTri_Click(object sender, EventArgs e)
		{
			numDecay.Value = 2.00M;
			numPhase.Value = 0.25M;
			numCombFreq.Value = 0.25M;
			numCombPhase.Value = 0.25M;
		}

		private void buttonPara_Click(object sender, EventArgs e)
		{
			numDecay.Value = 2.00M;
			numPhase.Value = 0.00M;
			numCombFreq.Value = 0.00M;
			numCombPhase.Value = 0.00M;
		}

		private void buttonRandom_Click(object sender, EventArgs e)
		{
			numDecay.Value = (decimal)(1.0 + _random.NextDouble());
			numPhase.Value = (decimal)(_random.NextDouble());
			numCombFreq.Value = (decimal)(_random.NextDouble());
			numCombPhase.Value = (decimal)(_random.NextDouble());
		}

		#endregion
	}
}
